home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 79 / maccd 79.iso / multimedial / GL Tron / Source / gltron / trail.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-07-10  |  9.6 KB  |  392 lines  |  [TEXT/CWIE]

  1. #include "gltron.h"
  2.  
  3. #define TEX_SPLIT (1.0 - BOW_DIST2) / (1 - BOW_DIST1)
  4. #undef TEX_SPLIT
  5.  
  6. static float normal1[] = { 1.0, 0.0, 0.0 };
  7. static float normal2[] = { 0.0, 1.0, 0.0 };
  8.  
  9. /* 
  10.    getDists returns the minimum distance from (the wall) *line to the
  11.    specified (eye) point
  12.    the z component is ignored
  13.  */
  14. float getDist(line *line, float* eye) {
  15.  
  16.   float n[2];
  17.   float tmp[2];
  18.   n[0] = line->sx + (line->ey - line->sy);
  19.   n[1] = line->sy - (line->ex - line->sx);
  20.   tmp[0] = eye[0] - line->sx;
  21.   tmp[1] = eye[1] - line->sy;
  22.   if(n[0] == n[1] == 0) return length(tmp);
  23.   return abs(scalarprod2(n, tmp) / length(n));
  24. }
  25.  
  26. /*
  27.   getSegmentEnd[XY]() returns the end point of the
  28.   last trail segment line (before the lightcycles bow starts)
  29. */
  30.  
  31. #define DECAL_WIDTH 20.0
  32. #define BOW_LENGTH 6
  33.  
  34. #define BOW_DIST3 2
  35. #define BOW_DIST2 0.85
  36. #define BOW_DIST1 0.4
  37.  
  38. float dists[] = { BOW_DIST2, BOW_DIST3, BOW_DIST1, 0 };
  39.  
  40. float getSegmentEndX(line *line, Data *data, int dist) {
  41.   float tlength, blength;
  42.  
  43.   if(dirsX[data->dir] == 0) return data->posx;
  44.  
  45.   tlength = data->posx - line->sx + data->posy - line->sy;
  46.   if(tlength < 0) tlength = -tlength;
  47.   blength = (tlength < 2 * BOW_LENGTH) ? tlength / 2 : BOW_LENGTH;
  48.   return data->posx - dists[dist] * blength * dirsX[ data->dir ];
  49. }
  50.  
  51. float getSegmentEndY(line *line, Data *data, int dist) {
  52.   float tlength, blength;
  53.   if(dirsY[data->dir] == 0) return data->posy;
  54.  
  55.   tlength = data->posx - line->sx + data->posy - line->sy;
  56.   if(tlength < 0) tlength = -tlength;
  57.   blength = (tlength < 2 * BOW_LENGTH) ? tlength / 2 : BOW_LENGTH;
  58.   return data->posy - dists[dist] * blength * dirsY[ data->dir ];
  59. }
  60.  
  61. /* getSegmentEndUV() calculates the texture coordinates for the last segment */
  62. float getSegmentEndUV(line *line, Data *data) {
  63.   float tlength, blength;
  64.   tlength = data->posx - line->sx + data->posy - line->sy;
  65.   if(tlength < 0) tlength = -tlength;
  66.   blength = (tlength < 2 * BOW_LENGTH) ? tlength / 2 : BOW_LENGTH;
  67.   return (tlength - 2 * blength) / DECAL_WIDTH;
  68. }
  69.  
  70. /* getSegmentUV gets UV coordinates for an ordinary segment */
  71. float getSegmentUV(line *line) {
  72.   float tlength;
  73.   tlength = line->ex - line->sx + line->ey - line->sy;
  74.   if(tlength < 0) tlength = -tlength;
  75.   return tlength / DECAL_WIDTH;
  76. }
  77.  
  78. #undef BOW_DIST1
  79. #undef BOW_DIST2
  80.  
  81.  
  82. #undef DECAL_WIDTH
  83. #undef BOW_LENGTH
  84.  
  85.  
  86. /* 
  87.    drawTrailLines() draws a white line on top of each trail segment
  88.    the alpha value is reduced with increasing distance to the player
  89. */
  90.  
  91. void drawTrailLines(Player *p) {
  92.   line *line;
  93.   float height;
  94.  
  95.   float *normal;
  96.   float dist;
  97.   float alpha;
  98.   Data *data;
  99.   Camera *cam;
  100.  
  101.   data = p->data;
  102.   cam = p->camera;
  103.  
  104.   height = data->trail_height;
  105.   if(height < 0) return;
  106.  
  107.   glDisable(GL_DEPTH_TEST);
  108.  
  109.   glEnable(GL_BLEND);
  110.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  111.   /* glDisable(GL_LIGHTING); */
  112.   glColor3f(1.0, 1.0, 1.0);
  113.   glBegin(GL_LINES);
  114.  
  115.   line = &(data->trails[0]);
  116.   while(line != data->trail) { /* the current line is not drawn */
  117.     /* compute distance from line to eye point */
  118.     dist = getDist(line, cam->cam);
  119.     alpha = (game->settings->grid_size - dist / 2) / game->settings->grid_size;
  120.     /* printf("dist: %.2f, alpha: %.2f\n", dist, alpha); */
  121.     glColor4f(1.0, 1.0, 1.0, alpha);
  122.     
  123.     if(line->sy == line->ey) normal = normal1;
  124.     else normal = normal2;
  125.     glNormal3fv(normal);
  126.     glVertex3f(line->sx, line->sy, height);
  127.     glVertex3f(line->ex, line->ey, height);
  128.     line++;
  129.     polycount++;
  130.   }
  131.   glEnd();
  132.   
  133.   glColor3f(1.0, 1.0, 1.0);
  134.   /* compute distance from line to eye point */
  135.   dist = getDist(line, cam->cam);
  136.   alpha = (game->settings->grid_size - dist / 2) / game->settings->grid_size;
  137.   /* printf("dist: %.2f, alpha: %.2f\n", dist, alpha); */
  138.   glColor4f(1.0, 1.0, 1.0, alpha);
  139.   glBegin(GL_LINES);
  140.  
  141.   glVertex3f(line->sx, line->sy, height);
  142.   glVertex3f( getSegmentEndX(line, data, 0),
  143.           getSegmentEndY(line, data, 0),
  144.           height );
  145.  
  146.   glEnd();
  147.  
  148.   /* glEnable(GL_LIGHTING); */
  149.   glDisable(GL_BLEND);
  150.  
  151.   glEnable(GL_DEPTH_TEST);
  152. }
  153.  
  154. /* 
  155.    drawTrailShadow() draws a alpha-blended shadow on the floor for each
  156.    trail segment.
  157.    The light source source is (in homogenous coordinates)
  158.    at (-1,-1,1,0) (I hope that's correct)
  159. */
  160.  
  161. #define SHADOWH 0.0
  162. void drawTrailShadow(Data* data) {
  163.   line *line;
  164.   float height;
  165.   /* draw trail shadow */
  166.  
  167.   height = data->trail_height;
  168.   if(game->settings->softwareRendering == 0) {
  169.     line = &(data->trails[0]);
  170.     glEnable(GL_BLEND);
  171.     glDisable(GL_DEPTH_TEST);
  172.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  173.     glColor4f(0.0, 0.0, 0.0, 0.6);
  174.     glBegin(GL_QUADS);
  175.  
  176.     line = &(data->trails[0]);
  177.     while(line != data->trail) { /* the current line is not drawn */
  178.       glNormal3f(0.0, 0.0, 1.0);
  179.       glVertex3f(line->sx, line->sy, SHADOWH);
  180.       glVertex3f(line->sx + height, line->sy + height, SHADOWH);
  181.       glVertex3f(line->ex + height, line->ey + height, SHADOWH);
  182.       glVertex3f(line->ex, line->ey, SHADOWH);
  183.       line++;
  184.       polycount++;
  185.     }
  186.     glVertex3f(line->sx, line->sy, SHADOWH);
  187.     glVertex3f(line->sx + height, line->sy + height, SHADOWH);
  188.     glVertex3f(data->posx + height, 
  189.            data->posy + height,
  190.            SHADOWH);
  191.     glVertex3f(data->posx, data->posy, SHADOWH);
  192.     glEnd();
  193.     glEnable(GL_DEPTH_TEST);
  194.   }
  195. }
  196. #undef SHADOWH
  197.  
  198. /*
  199.    drawTraces() draws all the trail segments.
  200.    The last one is split in three parts:
  201.    One ordinary part, one fading from trail color to white, and
  202.    a bow fading from white to the models color (that one is drawn
  203.    seperately in drawTrailBow() ).
  204. */
  205.  
  206. void drawTraces(Player *p, gDisplay *d) {
  207.   line *line;
  208.   float height;
  209.   float uv, ex, ey;
  210.   float normal1[] = { 1.0, 0.0, 0.0 };
  211.   float normal2[] = { 0.0, 1.0, 0.0 };
  212.   float *normal;
  213.   float color[4];
  214.  
  215.   Data *data;
  216.  
  217.   data = p->data;
  218.   height = data->trail_height;
  219.  
  220.   if(height < 0) return;
  221.  
  222.   /* calculate trail color and set blending modes */
  223.   if(game->settings->alpha_trails) {
  224.     glColor4fv(p->model->color_alpha);
  225.     glDepthMask(GL_FALSE);
  226.     glEnable(GL_BLEND);
  227.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  228.     setColor4fv(p->model->color_alpha);
  229.   } else {
  230.     if(game->settings->softwareRendering == 0) {
  231.       glDisable(GL_BLEND);
  232.       glEnable(GL_TEXTURE_2D);
  233.       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  234.       glBindTexture(GL_TEXTURE_2D, game->screen->textures[TEX_DECAL]);
  235.     }
  236.     setColor3fv(p->model->color_alpha);
  237.   }
  238.  
  239.   glShadeModel(GL_SMOOTH);
  240.  
  241.   /* start drawing */
  242.   line = &(data->trails[0]);
  243.   glBegin(GL_QUADS);
  244.   while(line != data->trail) { /* the last segment is special cased */
  245.  
  246.     if(line->sy == line->ey) normal = normal1;
  247.     else normal = normal2;
  248.  
  249.     /* glNormal3fv(normal); */
  250.     setNormal3fv(normal);
  251.     setVertex3f((line->sx + line->ex) / 2, (line->sy + line->ey) / 2, 0);
  252.     light4fv(color);
  253.     glColor4fv(color);
  254.  
  255.     glTexCoord2f(0.0, 0.0);
  256.     glVertex3f(line->sx, line->sy, 0.0);
  257.  
  258.     glTexCoord2f(0.0, 1.0);
  259.     glVertex3f(line->sx, line->sy, height);
  260.  
  261.     uv = getSegmentUV(line);
  262.     glTexCoord2f(uv, 1.0);
  263.     glVertex3f(line->ex, line->ey, height);
  264.  
  265.     glTexCoord2f(uv, 0.0);
  266.     glVertex3f(line->ex, line->ey, 0.0);
  267.  
  268.     line++;
  269.     polycount++;
  270.   }
  271.  
  272.   if(line->sy == data->posy) normal = normal1;
  273.   else normal = normal2;
  274.   /* glNormal3fv(normal); */
  275.  
  276.   /* calculate segment color */
  277.   setNormal3fv(normal);
  278.   setVertex3f(line->sx, line->sy, 0);
  279.   light4fv(color);
  280.   glColor4fv(color);
  281.     
  282.   glTexCoord2f(0.0, 0.0);
  283.   glVertex3f(line->sx, line->sy, 0.0);
  284.   glTexCoord2f(0.0, 1.0);
  285.   glVertex3f(line->sx, line->sy, height);
  286.  
  287.   /* modify end of trail */
  288.  
  289.   uv = getSegmentEndUV(line, data);
  290.   ex = getSegmentEndX(line, data, 1);
  291.   ey = getSegmentEndY(line, data, 1);
  292.  
  293.   glTexCoord2f(uv, 1.0);
  294.   glVertex3f(ex, ey, height);
  295.   glTexCoord2f(uv, 0.0);
  296.   glVertex3f(ex, ey, 0.0);
  297.  
  298.   polycount += 2;
  299.   glEnd();
  300.  
  301.   glDisable(GL_TEXTURE_2D);
  302.  
  303.   /* experimental trail effect */
  304.   checkGLError("before trail");
  305.  
  306.   glBegin(GL_QUADS);
  307.  
  308.   
  309.   /* glColor3f(1.0, 0.0, 1.0); */
  310.   glColor4fv(color);
  311.  
  312.   glVertex3f(ex, ey, 0);
  313.   glVertex3f(ex, ey, height);
  314.  
  315.   glColor3f(1.0, 1.0, 1.0);
  316.   ex = getSegmentEndX(line, data, 0);
  317.   ey = getSegmentEndY(line, data, 0);
  318.  
  319.   glVertex3f(ex, ey, height);
  320.   glVertex3f(ex, ey, 0);
  321.  
  322.   glEnd();
  323.  
  324.   glShadeModel( game->screen->shademodel );
  325.   glDisable(GL_BLEND);
  326.  
  327.   glDepthMask(GL_TRUE);
  328. }
  329.  
  330. void drawTrailBow(Player *p) {
  331.   Data *data;
  332.   float height;
  333.   float ex, ey, sx, sy;
  334.   int bdist;
  335.  
  336.   data = p->data;
  337.   height = data->trail_height;
  338.   if(height < 0) return;
  339.  
  340.   glShadeModel(GL_SMOOTH);
  341.  
  342.   if(data->speed > 0 && game->settings->show_model == 1) {
  343.     glEnable(GL_TEXTURE_2D);
  344.     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  345.     glEnable(GL_BLEND);
  346.     glBindTexture(GL_TEXTURE_2D, game->screen->textures[TEX_TRAIL]);
  347.     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  348.   }
  349.  
  350.  
  351.   bdist = (game->settings->show_model &&
  352.        data->speed > 0) ? 2 : 3;
  353.  
  354.   sx = getSegmentEndX(data->trail, data, 0);
  355.   sy = getSegmentEndY(data->trail, data, 0);
  356.  
  357.   ex = getSegmentEndX(data->trail, data, bdist);
  358.   ey = getSegmentEndY(data->trail, data, bdist);
  359.  
  360.     /* quad fading from white to model color, bow texture */
  361.   glBegin(GL_QUADS);
  362.  
  363.   /* glTexCoord2f(TEX_SPLIT, 0.0); */
  364.   glTexCoord2f(0.0, 0.0);
  365.   glColor3f(1.0, 1.0, 1.0);
  366.   glVertex3f(sx, sy, 0.0);
  367.  
  368.   glTexCoord2f(1.0, 0.0);
  369.   glColor3fv(p->model->color_model);
  370.   glVertex3f(ex, ey, 0.0);
  371.  
  372.   glTexCoord2f(1.0, 1.0);
  373.   glColor3fv(p->model->color_model);
  374.   glVertex3f(ex, ey, height);
  375.  
  376.   /* glTexCoord2f(TEX_SPLIT, 1.0); */
  377.   glTexCoord2f(0.0, 1.0);
  378.   glColor3f(1.0, 1.0, 1.0);
  379.   glVertex3f(sx, sy, height);
  380.   glEnd();
  381.  
  382.   polycount += 4;
  383.  
  384.   glShadeModel( game->screen->shademodel );
  385.   glDisable(GL_BLEND);
  386.   glDisable(GL_TEXTURE_2D);
  387.  
  388. }
  389.  
  390.  
  391.  
  392.